<?php
/**
 * Created by PhpStorm.
 * User: HS032
 * Date: 2020/7/21
 * Time: 10:39
 */

namespace pay\modules\frontend\controllers;



use GatewayWorker\Lib\Gateway;
use pay\libs\alipay\AliPayApi;
use pay\modules\frontend\models\Application;
use pay\libs\Curl;
use pay\libs\Tools;
use pay\modules\frontend\models\Order;
use pay\modules\frontend\models\OrderDetails;
use pay\modules\frontend\models\OrderInfo;
use pay\plug\CcbMainPay;
use Yii;
use yii\base\Exception;
use yii\log\FileTarget;
use yii\web\Controller;

class PayCallbackController extends Controller
{

    /*** 微信支付回调（已取消）
     * @return string
     */
    public function actionCallBackUrl()
    {
        //获取通知的数据
        $postStr = file_get_contents("php://input");
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($postObj === false) {
            $this->recordLogin(2000002,'支付回调通知数据',$postObj);
            die('parse xml error');
        }
        if ($postObj->return_code != 'SUCCESS') {
            die("error_code: " . $postObj->err_code . ",msg: " . $postObj->return_msg);
        }
        $this->recordLogin(500000005,'支付回调通知数据',$postObj->out_trade_no);
        /*更改订单状态*/
        // $postObj->out_trade_no = "2015883511555";
        $orderInfo = OrderInfo::find()->where('pay_order_sn = :sn', [':sn' => $postObj->out_trade_no])->one();
//        var_dump($orderInfo);die;
//        $this->recordLogin(600000000006,'支付回调通知数据',$orderInfo);
        if (!empty($orderInfo)) {
            // 修改订单信息
            $orderInfo->pay_status = 3;
            $orderInfo->real_money = $postObj->total_fee;
            $orderInfo->success_time = date("Y-m-d H:i:s");
            $orderInfo->pay_time = Tools::get_msectime();
            $orderInfo->wechat_sn = $postObj->transaction_id;
            $orderInfo->save(false);
        }
        $this->recordLogin(2000002,'支付回调通知数据',$postObj);
        $callbackUrl = $postObj->attach;
        if (!empty($callbackUrl)){
            $callParams = [
                'appId' => $orderInfo->app_id,
                'payStatus' => '00',
                'payNo' => $orderInfo->mar_order_sn,
                'orderSn' => $orderInfo->pay_order_sn,
                'payTime' => $orderInfo->success_time,
                'attach' => $orderInfo->attach,
                'nonceStr' => Tools::createStr(),
                'timeStamp' => time(),
            ];

            if ($this->callBack($callbackUrl,$callParams,$orderInfo->aid)){
                return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            }

        }else{
            return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        }

    }



    /*** 微信支付回调
     * @return string
     */
    public function actionCallWxBackUrl()
    {
//        //获取通知的数据
        $postStr = file_get_contents("php://input");
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($postObj === false) {
            $this->recordLogin(2000002,'支付回调通知数据',$postObj);
            die('parse xml error');
        }
        if ($postObj->return_code != 'SUCCESS') {
            die("error_code: " . $postObj->err_code . ",msg: " . $postObj->return_msg);
        }
        $this->recordLogin(500000005,'支付回调通知数据',json_encode($postObj));


        /*更改订单状态*/
        // $postObj->out_trade_no = "2015883511555";
        $orderInfo = Order::find()->where('pay_order_sn = :sn', [':sn' => $postObj->out_trade_no])->one();
        $orderDetails = OrderDetails::find()->where('oid = :oid',[':oid' => $orderInfo->oid])->one();
//        $this->recordLogin(600000000006,'支付回调通知数据',$orderInfo);
        if (!empty($orderInfo)) {
            // 修改订单信息
            $orderInfo->pay_status = 3;
            $orderInfo->real_money = $postObj->total_fee;
            $orderInfo->pay_times = date("Y-m-d H:i:s");
            $orderInfo->wechat_order_sn = $postObj->transaction_id;
            $orderInfo->save(false);

            if (!empty($orderDetails)){
                $orderDetails->pay_times = Tools::get_msectime();
                $orderDetails->save(0);

            }
        }

        if ($postObj->trade_type == 'NATIVE'){
            $data = array(
                'type' => 'payStatus',
                'data' => array(
                    'payNo' => $orderInfo->mar_order_sn,
                    'payStatus'  => 3,

                )
            );
            Gateway::sendToUid($orderInfo->mar_order_sn,json_encode($data));
            return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';

        }

        $callbackUrl = $orderDetails->callback_url;
        $this->recordLogin(0000,'支付回调通知参数',$orderDetails->remake);

        if (!empty($callbackUrl) and strstr($callbackUrl,'http')){
            $remake = json_decode($orderDetails->remake,true);
            if  (is_array($remake) && !empty($remake)){
                $remake = $remake;
            }else{
                $remake = $orderDetails->remake;
            }
            $this->recordLogin(11111,'支付回调通知参数',json_encode($remake));
            $callParams = [
                'appId' => $orderInfo->app_id,
                'payStatus' => '00',
                'payNo' => $orderInfo->mar_order_sn,
                'orderSn' => $orderInfo->pay_order_sn,
                'payTime' => $orderInfo->pay_times,
                'attach' => $remake,
                'nonceStr' => Tools::createStr(),
                'timeStamp' => time(),
            ];
            $this->recordLogin(22222,'支付回调通知参数',json_encode($callParams));
            if ($this->callBack($callbackUrl,$callParams,$orderInfo->aid)){
                return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            }

        }else{
            return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        }
    }


    /*** 支付宝支付回调
     * @return string
     */
    public function actionCallAliBackUrl()
    {
        if (Yii::$app->request->isPost) {
            $post = Yii::$app->request->post();
            $this->recordAli('10001','支付包回调参数',json_encode($post,JSON_UNESCAPED_UNICODE));
            $orderInfo = Order::find()->where('pay_order_sn = :sn', [':sn' => $post['out_trade_no']])->one();
            $orderDetails = OrderDetails::find()->where('oid = :oid',[':oid' => $orderInfo->oid])->one();
            $aliPayApi = new AliPayApi($orderDetails->channel_id);
            $falg = $aliPayApi->rsaCheckV1($post,'','RSA2');
            if ($falg){
                if  ($post['trade_status'] == 'TRADE_SUCCESS' || $post['trade_status'] == 'TRADE_FINISHED'){
                    if (!empty($orderInfo)) {
                        // 修改订单信息
                        $orderInfo->pay_status = 3;
                        $orderInfo->real_money = $post['total_amount'];
                        $orderInfo->pay_times = date("Y-m-d H:i:s");
                        $orderInfo->wechat_order_sn = $post['trade_no'];
                        $orderInfo->save(false);
                        if (!empty($orderDetails)){
                            $orderDetails->pay_times = Tools::get_msectime();
                            $orderDetails->save(0);
                        }
                    }
                    $callbackUrl = $orderDetails->callback_url;
                    $this->recordLogin(0000,'支付回调通知参数',$orderDetails->remake);

                    if (!empty($callbackUrl) and strstr($callbackUrl,'http')){
                        $remake = json_decode($orderDetails->remake,true);
                        if  (is_array($remake) && !empty($remake)){
                            $remake = $remake;
                        }else{
                            $remake = $orderDetails->remake;
                        }
                        $callParams = [
                            'appId' => $orderInfo->app_id,
                            'payStatus' => '00',
                            'payNo' => $orderInfo->mar_order_sn,
                            'orderSn' => $orderInfo->pay_order_sn,
                            'payTime' => $orderInfo->pay_times,
                            'attach' => $remake,
                            'nonceStr' => Tools::createStr(),
                            'timeStamp' => time(),
                        ];
                        if ($this->callBack($callbackUrl,$callParams,$orderInfo->aid)){
                            return "success";
                        }

                    }else{
                        return "success";
                    }
                }
            }
            $this->recordAli('9999','支付包验签失败'.$orderDetails->channel_id,json_encode($post,JSON_UNESCAPED_UNICODE));

        }


    }



    public function actionCallCcbBackUrl()
    {
        if (Yii::$app->request->isPost){
            $get = Yii::$app->request->get();
            $ccbMainPay = new CcbMainPay();
            $paramsData = $ccbMainPay->callBackData($get);
            $this->recordLogin(500000005,'建行支付回调通知数据',json_encode($get,JSON_UNESCAPED_UNICODE));

            /*更改订单状态*/
            // $postObj->out_trade_no = "2015883511555";
            $orderInfo = Order::find()->where('pay_order_sn = :sn', [':sn' => $paramsData['ORDERID']])->one();
            $orderDetails = OrderDetails::find()->where('oid = :oid',[':oid' => $orderInfo->oid])->one();
//        $this->recordLogin(600000000006,'支付回调通知数据',$orderInfo);
            if (!empty($orderInfo)) {
                // 修改订单信息
                $orderInfo->pay_status = 3;
                $orderInfo->real_money = $paramsData['PAYMENT']*100;
                $orderInfo->pay_times = date("Y-m-d H:i:s");
                $orderInfo->wechat_order_sn = '';
                $orderInfo->save(false);

                if (!empty($orderDetails)){
                    $orderDetails->pay_times = Tools::get_msectime();
                    $orderDetails->save(0);

                }
            }

            $callbackUrl = $orderDetails->callback_url;
            $this->recordLogin(0000,'支付回调通知参数',$orderDetails->remake);

            if (!empty($callbackUrl) and strstr($callbackUrl,'http')){
                $remake = json_decode($orderDetails->remake,true);
                if  (is_array($remake) && !empty($remake)){
                    $remake = $remake;
                }else{
                    $remake = $orderDetails->remake;
                }
                $this->recordLogin(11111,'支付回调通知参数',json_encode($remake));
                $callParams = [
                    'appId' => $orderInfo->app_id,
                    'payStatus' => '00',
                    'payNo' => $orderInfo->mar_order_sn,
                    'orderSn' => $orderInfo->pay_order_sn,
                    'payTime' => $orderInfo->pay_times,
                    'attach' => $remake,
                    'nonceStr' => Tools::createStr(),
                    'timeStamp' => time(),
                ];
                $this->recordLogin(22222,'支付回调通知参数',json_encode($callParams));
                if ($this->callBack($callbackUrl,$callParams,$orderInfo->aid)){
                    return 'SUCCESS';
                }

            }else{
                return 'SUCCESS';
            }

        }

    }
    
    
    public function actionTest()
    {
        $post = Yii::$app->request->post();
        $postObj = json_decode(json_encode($post));
        /*更改订单状态*/
        // $postObj->out_trade_no = "2015883511555";
        $orderInfo = Order::find()->where('pay_order_sn = :sn', [':sn' => $postObj->out_trade_no])->one();
        $orderDetails = OrderDetails::find()->where('oid = :oid',[':oid' => $orderInfo->oid])->one();
//        $this->recordLogin(600000000006,'支付回调通知数据',$orderInfo);
        if (!empty($orderInfo)) {
            // 修改订单信息
            $orderInfo->pay_status = 3;
            $orderInfo->real_money = $postObj->total_fee;
            $orderInfo->pay_times = date("Y-m-d H:i:s");
            $orderInfo->wechat_order_sn = $postObj->transaction_id;
            $orderInfo->save(false);

            if (!empty($orderDetails)){
                $orderDetails->pay_times = Tools::get_msectime();
                $orderDetails->save(0);

            }
        }

        if ($postObj->trade_type == 'NATIVE'){
            $data = array(
                'type' => 'payStatus',
                'data' => array(
                    'payNo' => $orderInfo->mar_order_sn,
                    'payStatus'  => 3,

                )
            );
            Gateway::sendToUid($orderInfo->mar_order_sn,json_encode($data));
            return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';

        }

        $callbackUrl = $orderDetails->callback_url;
        $this->recordLogin(0000,'支付回调通知参数',$orderDetails->remake);

        if (!empty($callbackUrl) and strstr($callbackUrl,'http')){
            $remake = json_decode($orderDetails->remake,true);
            if  (is_array($remake) && !empty($remake)){
                $remake = $remake;
            }else{
                $remake = $orderDetails->remake;
            }
            $this->recordLogin(11111,'支付回调通知参数',json_encode($remake));
            $callParams = [
                'appId' => $orderInfo->app_id,
                'payStatus' => '00',
                'payNo' => $orderInfo->mar_order_sn,
                'orderSn' => $orderInfo->pay_order_sn,
                'payTime' => $orderInfo->pay_times,
                'attach' => $remake,
                'nonceStr' => Tools::createStr(),
                'timeStamp' => time(),
            ];
            $this->recordLogin(22222,'支付回调通知参数',json_encode($callParams));
            if ($this->callBack($callbackUrl,$callParams,$orderInfo->aid)){
                return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            }

        }else{
            return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        }
    }

    /*** 支付回调通知
     * @param $url                  通知url
     * @param $params               通知参数
     * @return bool
     */
    protected function callBack($url,$params,$aid)
    {


        $key = (new Application())->getApplyKey($aid)['a_key'];

        $sign = Tools::computeSign($params,$key);
        $params['sign'] = $sign;
        $result = json_decode(Curl::post($url,$params),true);
        if ($result['relCode'] == 0){
            $this->recordLogin(000000,'支付回调通知,params:'.json_encode($params),json_encode($result));
            return true;
        }else{
            $this->recordLogin(999999,'支付回调通知失败,params:'.json_encode($params),json_encode($result));
            return false;
        }
    }

    protected function recordLogin($code,$msg,$data)
    {
        $log = new FileTarget();
        $log->logFile = Yii::$app->getRuntimePath() . '/payWx/pay_' . date('Ymd') . '.log';
        $log->messages[] = [
            "[url:{$_SERVER['REQUEST_URI']}],[data:{$code},{$msg},{$data}]",
            1,
            'application',
            time(),
        ];
        $log->export();
    }
    protected function recordAli($code,$msg,$data)
    {
        $log = new FileTarget();
        $log->logFile = Yii::$app->getRuntimePath() . '/payAli/pay_' . date('Ymd') . '.log';
        $log->messages[] = [
            "[url:{$_SERVER['REQUEST_URI']}],[data:{$code},{$msg},{$data}]",
            1,
            'application',
            time(),
        ];
        $log->export();
    }

    /*** 检查回调签名是否正确
     * @param $data
     * @return bool
     */
    public function checkBackSign($data,$channelMerId)
    {
        $paramsData  = json_decode(json_encode($data),true);
        $buff = "";
        ksort($paramsData);
        foreach ($paramsData as $k => $v) {
            if (null != $v && "null" != $v && $k != 'sign') {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        $reqPar = substr($buff, 0, strlen($buff) - 1);
//        var_dump($reqPar);die;

        $configModel = new Configuration();
        $configData = $configModel->Configuration($channelMerId);
        $key = $configData['key'];
        $sign = strtoupper(md5($reqPar . "&key=".$key));

        if ($sign == $paramsData['sign']){
            return true;
        }
        return false;
    }



    public function getPost()
    {
        $post = [
            "gmt_create" => "2020-11-06 13:41:27",
            "charset" => "utf8",
            "gmt_payment" => "2020-11-06 13:41:30",
            "notify_time" => "2020-11-06 13:41:31",
            "subject" => "我是标题",
            "sign" => "Q4HEshGUGmXubn7P4\/thDktdoOPUuATV\/BHxStCOYXjn9dMnFQdhQ4Io5pWpGVhpeTnTE3\/pOebeN1nDZ3MpeUP7O0dnCnJWgOCNILauzTP\/VnQ8NyWgwUD\/MKjqrkIuSZ92df6MZdetkNnWMmtCu9OAUQaxrnBjyeGGn7n7FAwyS+yTjVh5mh4qriA5TMHfmZDbOhoBcyh+2Bq9zqo9CtU8MDKB9iXXBkIJchP2afyuL4XzlU+3W6BDHHXSdIMz1mQlNBV6jBHc6\/1284gXCD707Xv8FHUvlL6phoPZyQp1w5D0pdBj8qRC0jNID\/t6A08On+shWdkOqUIFx3YLJA==",
            "buyer_id" => "2088312514789703",
            "invoice_amount" => "0.01",
            "version" => "1.0",
            "notify_id" => "2020110600222134130089701438538804",
            "fund_bill_list" => '[{"amount":"0.01","fundChannel":"PCREDIT"}]' ,
            "notify_type" => "trade_status_sync",
            "out_trade_no" => "20201106134112855951239",
            "total_amount" => "0.01",
            "trade_status" => "TRADE_SUCCESS",
            "trade_no" => "2020110622001489701405884781",
            "auth_app_id" => "2021002106693674",
            "receipt_amount" => "0.01",
            "point_amount" => "0.00",
            "buyer_pay_amount" => "0.01",
            "app_id" => "2021002106693674",
            "sign_type" => "RSA2",
            "seller_id" => "2088731673824083"

        ];
        return $post;
    }








}